/*
 * Copyright 2008 Andrej Herich
 * 
 * http://azetclient.yw.sk/
 * http://azetclient.googlecode.com/
 * 
 * This file is part of AzetClient.
 * 
 * AzetClient is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * AzetClient is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with AzetClient.  If not, see <http://www.gnu.org/licenses/>.
 */

package sk.yw.azetclient.azet;

import java.util.regex.Matcher;
import org.apache.log4j.Logger;
import sk.yw.azetclient.Main;

/**
 *
 * @author error216
 */
public class MessageCondenser {
    
    public static final Logger logger = Logger.getLogger(MessageCondenser.class);
    
    private class ParsedResult {
        
        private AzetMessageSplitterAndCondenser.MessageKey key;
        private int index;
        private int count;
        private String content;

        public AzetMessageSplitterAndCondenser.MessageKey getKey() {
            return key;
        }

        public void setKey(AzetMessageSplitterAndCondenser.MessageKey key) {
            this.key = key;
        }

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }

        public int getCount() {
            return count;
        }

        public void setCount(int count) {
            this.count = count;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }
    
    private AzetMessageSplitterAndCondenser.MessageKey key;
    private AzetMessageBean[] messages;
    private String[] contents;
    
    public MessageCondenser(Matcher condenseMatcher, AzetMessageBean message) {
        if (condenseMatcher == null)
            throw new IllegalArgumentException("Null pointer in condenseMatcher");
        if (condenseMatcher.groupCount() != 4)
            throw new IllegalArgumentException("condenseMatcher has illegal group count: "
                    + condenseMatcher.groupCount() + " != 4");
        
        if (message == null)
            throw new IllegalArgumentException("Null pointer in message");
        
        ParsedResult result = parseMatcher(condenseMatcher);
        key = result.getKey();
        messages = new AzetMessageBean[result.getCount()];
        contents = new String[result.getCount()];
        messages[result.getIndex() - 1] = message;
        contents[result.getIndex() - 1] = result.getContent();
    }
    
    public void add(Matcher condenseMatcher, AzetMessageBean message) {
        if (condenseMatcher == null)
            throw new IllegalArgumentException("Null pointer in condenseMatcher");
        if (condenseMatcher.groupCount() != 4)
            throw new IllegalArgumentException("condenseMatcher has illegal group count: "
                    + condenseMatcher.groupCount() + " != 4");
        
        if (message == null)
            throw new IllegalArgumentException("Null pointer in message");
        
        ParsedResult result = parseMatcher(condenseMatcher);
        if (!result.getKey().equals(key))
            throw new IllegalArgumentException("condenseMatcher - illegal key");
        if (result.getCount() != messages.length)
            throw new IllegalArgumentException("condenseMatcher - illegal count");
        
        messages[result.getIndex() - 1] = message;
        contents[result.getIndex() - 1] = result.getContent();
    }
    
    private ParsedResult parseMatcher(Matcher matcher) {
        ParsedResult result = new ParsedResult();
        
        try {
            result.setKey(AzetMessageSplitterAndCondenser.MessageKey
                    .valueOf(matcher.group(1)));
        } catch (IllegalArgumentException ex) {
            logger.error("Illegal message key: " + matcher.group(1), ex);
        }
        
        try {
            result.setIndex(Integer.parseInt(matcher.group(2)));
        } catch (NumberFormatException ex) {
            logger.error("Invalid number format of message index: " + matcher.group(2), ex);
        }
        
        try {
            result.setCount(Integer.parseInt(matcher.group(3)));
        } catch (NumberFormatException ex) {
            logger.error("Invalid number format of message count: " + matcher.group(3), ex);
        }
        
        result.setContent(matcher.group(4));
        
        return result;
    }
    
    public AzetMessageBean getCondensedMessage() {
        AzetMessageBean condensedMessage = new AzetMessageBean();
        
        // id
        for (AzetMessageBean message : messages) {
            if (message != null && message.getId() != 0L) {
                condensedMessage.setId(message.getId());
                break;
            }
        }
        
        // sender
        for (AzetMessageBean message : messages) {
            if (message != null && message.getSender() != null) {
                condensedMessage.setSender(message.getSender());
                break;
            }
        }
        
        // receiver
        for (AzetMessageBean message : messages) {
            if (message != null && message.getReceiver() != null) {
                condensedMessage.setReceiver(message.getReceiver());
                break;
            }
        }
        
        // sendTime
        for (AzetMessageBean message : messages) {
            if (message != null && message.getSendTime() != null) {
                condensedMessage.setSendTime(message.getSendTime());
                break;
            }
        }
        
        // timeOfPrevious
        for (AzetMessageBean message : messages) {
            if (message != null && message.getTimeOfPrevious() != null) {
                condensedMessage.setTimeOfPrevious(message.getTimeOfPrevious());
                break;
            }
        }
        
        // textOfPrevious
        for (AzetMessageBean message : messages) {
            if (message != null && message.getTextOfPrevious() != null) {
                condensedMessage.setTextOfPrevious(message.getTextOfPrevious());
                break;
            }
        }
        
        // sign, lastFragment
        for (int i = messages.length - 1; i >= 0; i--) {
            AzetMessageBean message = messages[i];
            if (message != null && message.getSign() != null) {
                condensedMessage.setSign(message.getSign());
                condensedMessage.setLastFragment(message.getContent());
                break;
            }
        }
        
        //content
        StringBuilder content = new StringBuilder();
        for(String part : contents) {
            if (part == null) {
                content.append(' ');
                content.append(Main.getProperty(
                        "azetclient.emptyMessagePartReplacementString"));
            } else {
                content.append(part);
            }
        }
        condensedMessage.setContent(content.toString());
        
        return condensedMessage;
    }
    
    public boolean isComplete() {
        for (AzetMessageBean message : messages) {
            if (message == null) return false;
        }
        return true;
    }

}